package com.dana.system.service.sysuser.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.core.constants.HttpConstants;
import com.core.domain.LoginUser;
import com.core.domain.Result;
import com.core.domain.vo.LoginUserVO;
import com.core.enums.ResultCode;
import com.core.enums.UserIdentity;

import com.dana.security.exception.ServiceException;
import com.dana.security.service.TokenService;
import com.dana.system.domain.sysuser.SysUser;
import com.dana.system.domain.sysuser.dto.SysUserSaveDTO;
import com.dana.system.mapper.sysuser.SysUserMapper;
import com.dana.system.service.sysuser.ISysUserService;
import com.dana.system.utils.BCryptUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;


//注解作用就是更新配置文件的时候可以不用重启服务
@RefreshScope
@Service
public class ISysUserServiceImpl extends ServiceImpl<SysUserMapper,SysUser>
        implements ISysUserService {
    //从配置上读取secret盐值
    @Value("${jwt.secret}")
    private String secret;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    TokenService tokenService;


    /**
     * 登录
     * @param userAccount 用户名
     * @param password 密码
     * @return token令牌,后续校验身份使用
     */
    @Override
    public Result<String> login(String userAccount, String password) {
        LambdaQueryWrapper<SysUser> queryWrapper=new LambdaQueryWrapper<>();
        //根据用户名(userAccount)查询用户相关信息,判断用户是否存在
        //select user_id,password,nick_name where user_account=#{userAccount}
        //查询出用户的id,密码,昵称等
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper.select(SysUser::getUserId,SysUser::getPassword,SysUser::getNickName)
                .eq(SysUser::getUserAccount, userAccount));
        //如果用户不存在
        if (sysUser==null){
            return Result.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        //将用户输入的密码根据密钥加密后和数据库比较
        if (!BCryptUtils.matchesPassword(password,sysUser.getPassword())) {
            return Result.fail(ResultCode.FAILED_LOGIN);
        }
        //校验成功生成token,token中存储UUID生成的唯一用户标识以及用户id
        //并将用户的身份和昵称缓存到redis中
        String token = tokenService.createToken(sysUser.getUserId(),
                secret, UserIdentity.ADMIN.getValue(),sysUser.getNickName(),null);

        //将生成的token返回给前端
        return Result.ok(token);
    }

    /**
     * 添加管理员
     * @param sysUserSaveDTO 管理员信息
     * @return 插入成功或者是失败
     */
    @Override
    public int add(SysUserSaveDTO sysUserSaveDTO) {
        //用户存在禁止注册,数据库查询该用户是否存在
        //select * from user where user_account=#{userAccount}
//        QueryWrapper<SysUser> queryWrapper=new QueryWrapper<>();
//        queryWrapper.eq("user_account", sysUserSaveDTO.getUserAccount());
//        SysUser isExits = sysUserMapper.selectOne(queryWrapper);

        SysUser isExits = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount, sysUserSaveDTO.getUserAccount()));

        if (isExits!=null){
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        //将sysUserSaveDTO转换为SysUser
        SysUser sysUser=new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
        //将用户存储到数据库
        return sysUserMapper.insert(sysUser);

    }

    /**
     * 获取当前登录用户的信息
     * 主要是展示登录后用户头像和用户名
     * @param token jwt令牌
     */
    @Override
    public Result<LoginUserVO> info(String token) {
        //将Bearer前缀去掉,解析出token
        String tokens = deleteBearer(token);
        //从redis中获取loginUser
        LoginUser loginUser = tokenService.getLoginUser(tokens, secret);
        if (loginUser == null) {
            return Result.fail();
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        //将loginUser赋值给loginUserVO并且返回给前端
        loginUserVO.setNickName(loginUser.getNickName());
        return Result.ok(loginUserVO);
    }

    /**
     * 管理员退出登录
     * 并删除redis中的tokenKey
     * @param token
     * @return
     */
    @Override
    public boolean logout(String token) {
        //获取token
        String tokens = deleteBearer(token);
        //退出登录后将redis缓存删除
        return tokenService.deleteLoginUser(tokens,secret);
    }


    /**
     * 删除将Bearer前缀
     * 前端传递token的时候会带上Bearer前缀+token
     * 拿到真正的token需要删除Bearer
     * @param token
     * @return
     */
    private String deleteBearer(String token){
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return token;
    }
   
}
